

package resources
{		
	import flash.display.Bitmap;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.utils.Dictionary;
	
	import br.com.stimuli.loading.BulkLoader;
	import br.com.stimuli.loading.BulkLoader;
	import br.com.stimuli.loading.BulkProgressEvent;
	import br.com.stimuli.loading.loadingtypes.LoadingItem;

	public class SceneImageResProvider  implements IResourceProvider
	{
		private var _loader:BulkLoader = null;
		private static const BulkLoaderName:String = "SceneImageResProvider";
		private static const BulkLoaderConnections:int = 5;
		
		protected var _updateProgress:Function;
		protected var _loadComplete:Function;
		
		//key identifier value imageresource
		protected var _resInfos:Dictionary;
		
		protected var _images:Vector.<int>;
		
		static private var _instance:SceneImageResProvider;
		static public function get instance():SceneImageResProvider
		{
			if(!_instance)
			{
				new SceneImageResProvider();
			}
			
			return _instance;
		}		
		
		public function SceneImageResProvider():void
		{
			if(_instance)
			{
				throw new Error("singleton error");
			}
			_instance = this;
			
			init();
		}
		
		private function init():void
		{
			_loader = new BulkLoader(BulkLoaderName, BulkLoaderConnections);
			_resInfos = new Dictionary();
			_images = new Vector.<int>;
			
			if (!_loader.hasEventListener(BulkProgressEvent.COMPLETE))
				_loader.addEventListener(BulkProgressEvent.COMPLETE, resourcesLoaded)
			
			if (!_loader.hasEventListener(BulkProgressEvent.PROGRESS))
				_loader.addEventListener(BulkProgressEvent.PROGRESS, resourcesProgress)
		}
		
		private function resourcesLoaded(event:BulkProgressEvent):void
		{
			// Create the Resource Objects and store them so the ResourceManager
			// can have access to them
			saveResources();
			
			// call the onloaded event/function if one was provided
			if (_loadComplete != null) _loadComplete();					  
		} 
		
		private function resourcesProgress(event:BulkProgressEvent):void
		{
			// call the onProgress event/function if one was provided 
			if (_updateProgress != null) _updateProgress(Math.round(event.percentLoaded*100),100);
		}
		
		private function saveResources():void
		{
			// register loaded resources with PBE as embedded resources
			for (var r:int=0; r<_images.length; r++)
			{
					var resourceIdentifier:String = _images[r].toString();
					// valid resource so try to get Content from BulkLoader
					if (_loader.getContent( resourceIdentifier )!=null)
					{
						// create a new resource of type
						var resource:Resource = new ImageResource();
						
						// get content from bulkLoader and release memory
						var content:* = _loader.getContent( resourceIdentifier , true);
						resource.filename = resourceIdentifier;
						
						// initalize resource with the content from bulkloader						
						if (content is Bitmap)
						{
							// initialize the ImageResource with a copy of the 'raw' BitmapData
							resource.initialize((content as Bitmap).bitmapData);
							// set variable of this Bitmap to null so it will be picked up by GC 
							content = null;
						}
						else
							resource.initialize(content);
						
						// set lookup for later resource retrieval						
						_resInfos[resourceIdentifier] = resource;
					}
				}				
						
		}
		
		public function startPreLoad(updateProgress:Function,loadComplete:Function):void
		{
			this._updateProgress = updateProgress;
			this._loadComplete = loadComplete;
		}
		
		public function getImage(url:String,identifier:int,forceReload:Boolean = false):Resource
		{
			// if resource is known return it.
			if (_resInfos[identifier]!=null && !forceReload) 
			{
				return _resInfos[identifier];
			}
			
			if (_loader.get(identifier)!=null)
				_loader.remove(identifier);
			
			// the resource has to be loaded so add to BulkLoader
			// Special case so that MP3Resource gets a sound like it wants.
			_loader.add(url, { id : identifier, type:"image"  } );
			if (!_loader.isRunning) _loader.start();	
			
			// let BulkLoader give a notification when this resource has been
			// load so we can initialize it.
			_loader.get(identifier).addEventListener(Event.COMPLETE,resourceLoaded)
			_loader.get(identifier).addEventListener(BulkLoader.ERROR,resourceError)
			
			if (_resInfos[identifier]==null)
			{
				// create resource and provide it to the ResourceManager
				var resource:ImageResource = new ImageResource();
				resource.filename = identifier.toString();
				_resInfos[identifier] = resource;
			}
			else
				resource = _resInfos[identifier];			
			
			return resource;
		}
		
		public function addImage(url:String,identifier:int):void
		{
			_loader.add(url, { id : identifier, type:"image"  } );
			_images.push(identifier);
		}
		
		private function resourceLoaded(event:Event):void
		{
			// if resource of current LoadingItem exists, initialize it. 			
			if (_resInfos[(event.currentTarget as LoadingItem).id]!=null)
			{
				// get content from bulkLoader and release memory
				var content:* = _loader.getContent( (event.currentTarget as LoadingItem).id , true);			   
				
				// initalize resource with the content from bulkloader						
				if (content is Bitmap)
				{
					// initialize the ImageResource with a copy of the 'raw' BitmapData
					(_resInfos[(event.currentTarget as LoadingItem).id] as Resource).initialize((content as Bitmap).bitmapData);
					// set variable of this Bitmap to null so it will be picked up by GC 
					content = null;
				}
				else
					(_resInfos[(event.currentTarget as LoadingItem).id] as Resource).initialize(content);
			}
		}
		
		private function resourceError(event:ErrorEvent):void
		{
			// if resource of current LoadingItem exists, notify that is has failed 			
			if (_resInfos[(event.currentTarget as LoadingItem).id]!=null)
			{
				(_resInfos[(event.currentTarget as LoadingItem).id] as Resource).fail(event.text);
			}
		}		
		
		public function startLoad():void
		{
			// start the BulkLoader loading process
			if (!_loader.isRunning)
				_loader.start();
		}
		
		public function clearAllImages():void
		{
			for each (var v:ImageResource in _resInfos)
			{
				v = null;
			}
			
			_images.splice(0,_images.length);
			_loader.clear();
			
			_loader = new BulkLoader(BulkLoaderName, BulkLoaderConnections);
		}
		
		public function set loadItemTimeInterval(v:int):void
		{
			
		}
		public function get loadItemTimeInterval():int
		{
			return 0;
		}
		
		public function getRes(id:int):ImageResource
		{
			return _resInfos[id];
		}
	}
}